import sys
import json

from cc.appcoin2.support.py_module.py_driver import PyDriver, PyLogger
from cc.appcoin2.support.symbology.py_symbology import PyProduct


class StrategyBase:
  def __init__(self, driver_config):
    self._driver_config = driver_config
    self._driver = None
    self._og_name_list = []

    self._cpp_log_file_path = None
    self._redirect_py_print = False

    self._enable_telemetry = False

  def redirect_cpp_log_to_file(self, log_path, redirect_py_print: bool):
    if not log_path:
     return
    # TODO: check file path
    self._cpp_log_file_path = log_path
    self._redirect_py_print = redirect_py_print

  def run(self):
    # redirect log
    if self._cpp_log_file_path:
      print("redirect cpp log to file: {}".format(self._cpp_log_file_path))
      PyDriver.redirect_cpp_log(self._cpp_log_file_path, 2)
    if self._redirect_py_print and self._cpp_log_file_path:
      print("redirect py log to file: {}".format(self._cpp_log_file_path))
      sys.stdout = PyLogger()
    # start driver
    self._driver = PyDriver(self._driver_config, self, self._enable_telemetry)
    self._driver.run()

  def get_all_working_orders(self, me='ALL'):
    working_orders = []
    for og_name in self._og_name_list:
      og = self._driver.get_og_by_name(og_name)
      if me != 'ALL' and me not in og.mea:
        continue
      inner_working_orders = og.get_all_working_orders()
      for order in inner_working_orders:
        working_orders.append(order.as_dict())
    return working_orders

  def submit_order(self, exec_spec: dict):
    if 'og_name' not in exec_spec:
      return
    if 'order_spec' not in exec_spec:
      return
    og_name = exec_spec['og_name']
    if og_name not in self._og_name_list:
      return;
    og = self._driver.get_og_by_name(og_name)
    if not og.is_ready():
      return
    order_spec = exec_spec['order_spec']
    og.submit_order(order_spec)

  def cancel_order(self, exec_spec: dict):
    if 'og_name' not in exec_spec:
      return
    if 'proc_order_id' not in exec_spec:
      return
    og_name = exec_spec['og_name']
    if og_name not in self._og_name_list:
      return;
    og = self._driver.get_og_by_name(og_name)
    if not og.is_ready():
      return
    proc_order_id = exec_spec['proc_order_id']
    og.cancel_order(proc_order_id)
